use std::{
    collections::HashMap,
    fs::{create_dir_all, OpenOptions},
    io::{Error, Write},
    sync::{Arc, Mutex},
    thread::sleep,
    time::{Duration, Instant},
};

use rayon::prelude::{IntoParallelIterator, ParallelIterator};
use spades_lib::{
    round,
    utils::{self, Utils},
};
use spades_sim::{
    sim_condition::ScoreConditionEnum,
    sim_model::{SpadesMatchData, SpadesSimModel},
};
use tge::{context::Context, game::Model, log::init_log};

fn main() {
    init_log(log::LevelFilter::Error, "log/spades_sim.log");
    sim_match();
}

fn sim_match() {
    let mut num_threads = 64; // 设置线程数量
    let delay_ms = 5; //注意这里的round的随机种子取值是取的时间戳毫秒级别
    let score_condition_id = ScoreConditionEnum::ScoreC as i32;
    let condition_id = 0;
    let condition_count = 20000;
    //2v2
    let group_count: i32 = 8; //8:2v2  8:solo
    let play_mode = 1; //1:2v2 2:solo
    let gen_type: i16 = 1; //test 0,prod 1
    let team_max_delta = 80; //80:2v2 120:solo
    let team_step_delta = 40; //40:2v2 60:solo
    //solo
    // let group_count: i32 = 8; //8:2v2  8:solo
    // let play_mode = 2; //1:2v2 2:solo
    // let gen_type: i16 = 1; //test 0,prod 1
    // let team_max_delta = 120; //80:2v2 120:solo
    // let team_step_delta = 60; //40:2v2 60:solo

    num_threads = std::cmp::min(num_threads, condition_count);
    //shared counter
    let matched_count = Arc::new(Mutex::new(0));
    //a flag to signal stopping
    // let should_stop: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
    let should_stop_mutex: Arc<Mutex<bool>> = Arc::new(Mutex::new(false));
    let match_bags: Arc<Mutex<HashMap<i32, usize>>> = Arc::new(Mutex::new(HashMap::new()));
    // 创建一个字典来存储已经写入数据的次数
    let written_counts: Arc<Mutex<HashMap<String, i32>>> = Arc::new(Mutex::new(HashMap::new()));
    let condition_counts: Arc<Mutex<HashMap<String, i32>>> = Arc::new(Mutex::new(HashMap::new()));
    // Start a timer to track elapsed time
    let start_time = Instant::now();
    (0..num_threads).into_par_iter().for_each(move |_| {
        // while !should_stop.load(Ordering::Relaxed) {
        while !should_stop_mutex.lock().unwrap().clone() {
            let mut check_crest = true;
            {
                let mut written_counts = written_counts.lock().unwrap();
                let mut condition_counts = condition_counts.lock().unwrap();
                if written_counts.len() == 0 {
                    for key in (0..=team_max_delta).step_by(team_step_delta) {
                        let key2 = format!("{0}_{1}", "pool_1", key);
                        written_counts.insert(key2.clone(), 0);
                        condition_counts.insert(key2.clone(), 9 * condition_count);

                        let key3 = format!("{0}_{1}", "pool_2", key);
                        written_counts.insert(key3.clone(), 0);
                        condition_counts.insert(key3.clone(), 9 * condition_count);
                    }
                    // if play_mode == 1 {
                    //     for key in (0..=team_max_delta).step_by(team_step_delta) {
                    //         let key2 = format!("{0}_{1}", "pool_1_", key);
                    //         written_counts.insert(key2.clone(), 0);
                    //         condition_counts.insert(key2.clone(), 9 * condition_count);

                    //         let key3 = format!("{0}_{1}", "pool_2_", key);
                    //         written_counts.insert(key3.clone(), 0);
                    //         condition_counts.insert(key3.clone(), 1 * condition_count);
                    //     }
                    // } else {
                    //     let mut count = matched_count.lock().unwrap();
                    //     for key in (0..=solo_max_delta).step_by(solo_step_delta) {
                    //         for key2 in (0..=solo_max_delta).step_by(solo_step_delta) {
                    //             if key2 >= key {
                    //                 let key = format!("{0}_{1}", key, key2);
                    //                 written_counts.insert(key.clone(), 0);
                    //                 condition_counts.insert(key.clone(), condition_count);
                    //             } else {
                    //                 //不合理的分数段 1 4 不可能比 13要低 直接算完成
                    //                 *count += 1;
                    //             }
                    //         }
                    //     }
                    // }
                    written_counts.insert(String::from("crest"), 0);
                    condition_counts.insert(String::from("crest"), 9 * condition_count);
                    written_counts.insert(String::from("trough"), 0);
                    condition_counts.insert(String::from("trough"), 9 * condition_count);
                }

                let score_id_count_crest = written_counts.entry(String::from("crest")).or_insert(0);
                let condition_count_crest =
                    condition_counts.entry(String::from("crest")).or_insert(0);
                check_crest = *score_id_count_crest < *condition_count_crest;
            }
            let mut check_trough = true;
            {
                let mut written_counts = written_counts.lock().unwrap();
                let mut condition_counts = condition_counts.lock().unwrap();
                let score_id_count_trough =
                    written_counts.entry(String::from("trough")).or_insert(0);
                let condition_count_trough =
                    condition_counts.entry(String::from("trough")).or_insert(0);
                check_trough = *score_id_count_trough < *condition_count_trough;
            }

            let sim_game_result = sim_game(
                score_condition_id,
                condition_id,
                play_mode,
                check_crest,
                check_trough,
            );
            match sim_game_result {
                Ok(data) => {
                    let mut written_counts = written_counts.lock().unwrap();
                    let mut condition_counts = condition_counts.lock().unwrap();
                    let mut group_id = data.group_id.to_string();
                    match data.write_pool_type {
                        1 => {
                            group_id = String::from("crest");
                        }
                        2 => {
                            group_id = String::from("trough");
                        }
                        3 => {
                            group_id = format!("{0}_{1}", "pool_2", group_id);
                        }
                        4 => {
                            group_id = format!("{0}_{1}", "pool_1", group_id);
                        }
                        _ => {
                            println!(
                                "未知分组 {} {}",
                                data.write_pool_type,
                                data.group_id.to_string(),
                            );
                        }
                    }
                    let score_id_count = written_counts.entry(group_id.clone()).or_insert(0);
                    let condition_count = condition_counts.entry(group_id.clone()).or_insert(0);
                    if *score_id_count < *condition_count {
                        let save_game = save_game(
                            &data,
                            group_id.clone(),
                            condition_id,
                            gen_type,
                            play_mode,
                            *score_id_count,
                        );
                        match save_game {
                            Ok(_) => {
                                let score_id_count =
                                    written_counts.entry(group_id.clone()).or_insert(0);
                                if *score_id_count < *condition_count {
                                    *score_id_count += 1;
                                    if *score_id_count >= *condition_count {
                                        println!("{} data is full", group_id.clone());
                                        let mut count = matched_count.lock().unwrap();
                                        *count += 1;
                                    }
                                    println!(
                                        "save data success id {} {}",
                                        group_id.clone(),
                                        *score_id_count
                                    );
                                    // let mut is_all_finished = true;
                                    // for (_, value) in written_counts.iter() {
                                    //     if *value < group_count {
                                    //         is_all_finished = false;
                                    //     }
                                    // }
                                    // if is_all_finished {
                                    //     let mut guard = should_stop_mutex.lock().unwrap();
                                    //     *guard = true;
                                    // }
                                }
                            }
                            Err(_) => {
                                // println!("save data fail id {}", *count);
                            }
                        }
                        let team_bags = data.team_bags;
                        let mut distribution = match_bags.lock().unwrap();
                        for bag in team_bags {
                            let count = distribution.entry(bag as i32).or_insert(0);
                            *count += 1;
                        }
                    }
                }
                Err(err) => {
                    println!("data is not met: {}", err.to_string());
                }
            }
            // Check if we should stop based on the total matched count
            let total_matched = matched_count.lock().unwrap().clone();
            if total_matched >= group_count {
                // println!("all data is gen {}", total_matched);
                // should_stop.store(true, Ordering::Relaxed);
                let mut guard = should_stop_mutex.lock().unwrap();
                *guard = true;
                println!("all group gen finished");
                // let distribution = match_bags.lock().unwrap().clone();
                // for (team_bags, count) in distribution.iter() {
                //     println!("match team_bags: {:?}, count: {}", team_bags, count);
                // }
            }
            sleep(Duration::from_millis(5));
        }
    });

    // Calculate and print elapsed time
    let elapsed_time = start_time.elapsed();
    println!("Elapsed time: {:?}", elapsed_time);
}
fn format_vec_of_vec(vec: &Vec<Vec<i16>>) -> String {
    let formatted: Vec<String> = vec
        .iter()
        .map(|inner_vec| {
            let inner_formatted: Vec<String> = inner_vec.iter().map(|v| v.to_string()).collect();
            format!("[{}]", inner_formatted.join(","))
        })
        .collect();
    formatted.join(",")
}
fn save_game(
    match_data: &SpadesMatchData,
    group_id: String,
    condition_id: i32,
    gen_type: i16,
    play_mode: i16,
    row_num: i32,
) -> Result<(), Error> {
    //if condition_id>0 {format!("dist/{}/{}/", score_id, condition_id)}else{format!("dist/{}/", score_id)};
    let gen_path = if gen_type == 1 { "prod" } else { "test" };
    let folder_name = format!("dist/{}_{}/{}", gen_path, play_mode, group_id);
    let file_name = format!("{}/{}.json", folder_name, condition_id);
    let path_name = format!(
        "{}_{}_{}_{}_{}_{}",
        gen_path, play_mode, group_id, match_data.write_condition_type, condition_id, row_num
    );
    // 创建文件夹（如果不存在）
    create_dir_all(folder_name)?;

    let dealer_index = match_data.banker_ranks[4];
    let seat_rank_list = &match_data.banker_ranks[..4];
    let cards_list = &match_data.cards;
    let bid_list = &match_data.bids;
    let made_list = &match_data.tricks;
    let cards_id = path_name;
    let json_string = format!(
        r#"{{"cardsId": "{}","seatRankList": [{},{},{},{}],"cardsList": [{}],"bidList": [{}],"madeList": [{}],"dealerIndex": "{}"}}"#,
        cards_id,
        seat_rank_list[0],
        seat_rank_list[1],
        seat_rank_list[2],
        seat_rank_list[3],
        format_vec_of_vec(&cards_list),
        format_vec_of_vec(&bid_list),
        format_vec_of_vec(&made_list),
        dealer_index
    );
    let data: String = format!("{}{}", json_string, "\n");
    let bytes = data.as_bytes();
    let mut file = OpenOptions::new()
        .create(true)
        .append(true)
        .open(file_name)?;
    file.write_all(bytes)?;

    //再存一份叫分的
    // let bid_folder_name = format!("bid/{}_{}/{}", gen_path, play_mode, group_id);
    // let bid_file_name = format!("{}/{}.json", bid_folder_name, condition_id);

    // create_dir_all(bid_folder_name)?;
    // let data: String = format!(
    //     "{},{}{}{}{}",
    //     serde_json::to_string(&match_data.banker_ranks).unwrap(),
    //     serde_json::to_string(&match_data.bids).unwrap(),
    //     serde_json::to_string(&match_data.tricks).unwrap(),
    //     serde_json::to_string(&match_data.team_scores).unwrap(),
    //     "\n"
    // );
    // let bid_bytes = data.as_bytes();
    // let mut bid_file = OpenOptions::new()
    //     .create(true)
    //     .append(true)
    //     .open(bid_file_name)?;
    // bid_file.write_all(bid_bytes)?;

    Ok(())
}
fn sim_game(
    score_id: i32,
    _condition_id: i32,
    mode: i16,
    check_crest: bool,
    check_through: bool,
) -> Result<SpadesMatchData, Error> {
    let mut ctx = Context::new();
    let mut m: SpadesSimModel = SpadesSimModel::new(score_id);
    let table = &mut m.table;
    table.mode = mode;
    let final_score_1 = 100;
    let final_score_2 = 40;
    if mode == 1 {
        table.final_score = final_score_1;
        table.limit_bag = 5;
        table.score_trick = 10;
        table.score_bag = 1;
        table.score_nil = 70;
        table.score_blind_nil = 140;
        table.score_bag_penalty = 50;
        table.score_lose = -100;
        table.joker = 0;
    } else {
        table.final_score = final_score_2;
        table.limit_bag = 3;
        table.score_trick = 10;
        table.score_bag = 1;
        table.score_nil = 50;
        table.score_blind_nil = 100;
        table.score_bag_penalty = 50;
        table.score_lose = -60;
        table.joker = 0;
    }

    m.init(&mut ctx);

    let match_data = &mut m.match_data;

    //添加牌局筛选条件
    // ○ 小局数大于2场的（打到第3局就可以不用继续了）
    // ○ 任意单局，任意玩家最少的花色牌大于2张（可以想办法改一下发牌逻辑直接实现这条）
    // ○ 任意单局没有spades broken的（第一张黑桃出牌是杀牌而不是首位出牌）
    // ○ 任意单局黑桃杀次数小于3次，黑桃杀定义：首位出的非黑桃，后3位有人出黑桃算1次，有多个人出黑桃也只算1次

    let rounds = &match_data.rounds;
    if rounds.len() > 2 {
        return Err(std::io::Error::new(
            std::io::ErrorKind::Other,
            format!("单局回合数 {0} 大于 2 不记录 ", rounds.len()),
        ));
    }

    for round in rounds {
        if round.data.spades_broken == 0 {
            return Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                "单局没有破黑桃 不记录 ",
            ));
        }
        if round.data.spades_break_times < 3 {
            return Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                format!(
                    "黑桃杀次数 {0} 小于 3 不记录 ",
                    round.data.spades_break_times
                ),
            ));
        }
        //todo 这个条件可以移到发牌阶段打断比赛
        let player_min_suit_counts = round.data.players_min_suit;
        for suit_count in player_min_suit_counts {
            if suit_count > 2 {
                return Err(std::io::Error::new(
                    std::io::ErrorKind::Other,
                    format!("有玩家最少花色数 {0} 大于 2 不记录 ", suit_count),
                ));
            }
        }
        let bids: &Vec<i16> = &round.bids;
        let tricks = &round.tricks;
        if mode == 1 {
            //单局 组队叫分>=7 且未达成
            if bids[0] + bids[2] >= 7 && tricks[0] + tricks[2] < 7
                || bids[1] + bids[3] >= 7 && tricks[1] + tricks[3] < 7
            {
                return Err(std::io::Error::new(
                    std::io::ErrorKind::Other,
                    format!("任意单局，组队叫分>=7且未达成（2v2 不记录 "),
                ));
            }
        } else if mode == 2 {
            //单局个人叫分>=5 且未达成
            for (index, &value) in bids.iter().enumerate() {
                if value >= 5 && tricks[index] < 5 {
                    return Err(std::io::Error::new(
                        std::io::ErrorKind::Other,
                        format!("个人叫分>=5分且未达成 不记录 "),
                    ));
                }
            }
        }
        for (index, &value) in bids.iter().enumerate() {
            if value == 1 && tricks[index] <= 1 {
                return Err(std::io::Error::new(
                    std::io::ErrorKind::Other,
                    format!("个人叫1分且最终得分0分或者1分"),
                ));
            }
        }
        if round.data.has_bag_penalty {
            return Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                format!("有破袋情况 不记录 "),
            ));
        }
    }
    let mut write_pool_type = 0;
    let mut write_conditon_type = 0;
    let mut mark_sead_id: i8 = -1;
    if match_data.team_win_id == -1 {
        return Err(std::io::Error::new(
            std::io::ErrorKind::Other,
            "not found win team",
        ));
    } else {
        let win_team_id = match_data.team_win_id;
        if mode == 1 {
            let delta = (match_data.team_scores[0] - match_data.team_scores[1]).abs() as i32;
            // 一局结束，通过赢分胜利，且领先对手60分以上，获胜方叫分高的作为1号位，归入波峰牌库
            if check_crest {
                let is_score_win =
                    match_data.team_scores[match_data.team_win_id as usize] >= final_score_1;
                if is_score_win && match_data.rounds.len() == 1 {
                    let mut is_win_without_bid_nil = true;
                    let bid_nil_times = match_data.player_nil_times;
                    if win_team_id == 0 {
                        if bid_nil_times[0] > 0 || bid_nil_times[2] > 0 {
                            is_win_without_bid_nil = false;
                        }
                    } else if win_team_id == 1 {
                        if bid_nil_times[1] > 0 || bid_nil_times[3] > 0 {
                            is_win_without_bid_nil = false;
                        }
                    }

                    if delta > 60 && is_win_without_bid_nil {
                        let round = &match_data.rounds[0];
                        if win_team_id == 0 {
                            if round.bids[0] > round.bids[2] {
                                mark_sead_id = 0;
                            } else if round.bids[0] == round.bids[2] {
                                if round.scores[0] > round.scores[2] {
                                    mark_sead_id = 0;
                                } else {
                                    mark_sead_id = 2;
                                }
                            } else {
                                mark_sead_id = 2;
                            }
                        } else if win_team_id == 1 {
                            if round.bids[1] > round.bids[3] {
                                mark_sead_id = 1;
                            } else if round.bids[1] == round.bids[3] {
                                if round.scores[1] > round.scores[3] {
                                    mark_sead_id = 1;
                                } else {
                                    mark_sead_id = 3;
                                }
                            } else {
                                mark_sead_id = 3;
                            }
                        }
                        write_pool_type = 1;
                        write_conditon_type = 1;
                    }
                }
                // 同一位置每小局杀牌成功次数都大于2次，且最终赢分胜利，该位置为1号位，归入波峰牌库
                // if write_pool_type == 0 {
                //     let mut seat_spades_win = [true, true, true, true];
                //     for round in rounds {
                //         let break_wins = round.data.players_break_win;
                //         for idx in 0..=3 {
                //             if break_wins[idx] < 2 {
                //                 seat_spades_win[idx] = false;
                //             }
                //         }
                //     }
                //     for sid in 0..=3 {
                //         if seat_spades_win[sid]
                //             && utils::Utils::get_team_by_player_id(sid, 1) == (win_tid as usize)
                //         {
                //             write_pool_type = 1;
                //             mark_sead_id = sid as i8;
                //             break;
                //         }
                //     }
                // }
                //任意小局叫0成功，且最终赢分胜利，分差大于40分，该位置为1号位，归入波峰牌库
                if write_pool_type == 0 {
                    let mut is_win_with_nil = false;
                    let mut bid_seat_id = -1;
                    for round in rounds {
                        if (round.data.win_team_id as i16) == win_team_id
                            && round.data.is_win_bid_nil > 0
                        {
                            is_win_with_nil = true;
                            bid_seat_id = round.data.is_win_bid_nil;
                            break;
                        }
                    }
                    if is_win_with_nil && delta > 40 {
                        write_pool_type = 1;
                        write_conditon_type = 2;
                        mark_sead_id = bid_seat_id;
                    }
                }
                //2局结束，第一小局双方都是正分且分差大于等于30分，第二小局双方都达成叫分，落后方通过赢分胜利，获胜方第二局叫分高的位置为1号位，归入波峰牌库（条件3）
                if write_pool_type == 0 {
                    if match_data.rounds.len() == 2 {
                        let round_one = &match_data.rounds[0];
                        let round_one_teams = &round_one.data.teams;
                        let team_a = round_one_teams[0].match_score;
                        let team_b = round_one_teams[1].match_score;

                        let round_two = &match_data.rounds[1];
                        if team_a > 0 && team_b > 0 && (team_a - team_b).abs() >= 30 {
                            //双方都达成叫分
                            let mut is_all_finish_bid = true;
                            for idx in 0..=3 {
                                let bids = &round_two.bids;
                                let tricks = &round_two.tricks;
                                if tricks[idx] < bids[idx] {
                                    is_all_finish_bid = false;
                                    break;
                                }
                                if bids[idx] == 0 && tricks[idx] > 0 {
                                    is_all_finish_bid = false;
                                    break;
                                }
                            }
                            let team_a_score = match_data.team_scores[0];
                            let team_b_score = match_data.team_scores[1];
                            if is_all_finish_bid {
                                if team_a > team_b && win_team_id == 1 {
                                    if team_b_score - team_a_score > 10 {
                                        //记录反超队伍中 第二局贡献大的位置
                                        if round_two.bids[1] > round_two.bids[3] {
                                            mark_sead_id = 1;
                                        } else {
                                            mark_sead_id = 3;
                                        }
                                        write_pool_type = 1;
                                        write_conditon_type = 3;
                                    }
                                } else if team_a < team_b && win_team_id == 0 {
                                    if team_a_score - team_b_score > 10 {
                                        if round_two.bids[0] > round_two.bids[2] {
                                            mark_sead_id = 0;
                                        } else {
                                            mark_sead_id = 2;
                                        }
                                        write_pool_type = 1;
                                        write_conditon_type = 3;
                                    }
                                }
                            }
                        }
                    }
                }
                if write_pool_type == 0 {
                    if match_data.rounds.len() == 2 {
                        let round_one = &match_data.rounds[0];
                        let round_two = &match_data.rounds[1];
                        for sid in 0..=3 {
                            let s_team_id = utils::Utils::get_team_by_player_id(sid, 1) as i16;
                            if round_one.bids[sid] + round_two.bids[sid] >= 9
                                && round_one.bids[sid] <= round_one.tricks[sid]
                                && round_two.bids[sid] <= round_two.tricks[sid]
                            {
                                let partner_id = utils::Utils::get_partner_player_id(sid);
                                if round_one.bids[partner_id] + round_two.bids[partner_id] == 4
                                    && round_one.bids[partner_id] <= round_one.tricks[partner_id]
                                    && round_two.bids[partner_id] <= round_two.tricks[partner_id]
                                {
                                    if s_team_id == win_team_id {
                                        mark_sead_id = sid as i8;
                                        write_pool_type = 1;
                                        write_conditon_type = 4;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if check_through && write_pool_type == 0 {
                //同一位置每小局最少花色小于2张且黑桃张数都大于3张，最终失败，该位置为1号位，归入波谷牌库
                let fail_team_id = if win_team_id == 0 { 1 } else { 0 };
                //同一位置每小局最少花色小于2张且黑桃张数都大于3张，最终失败，该位置为1号位
                let mut seat_condition = [true, true, true, true];
                // for round in rounds {
                //     let min_suits = round.data.players_min_suit;
                //     let spades_count = round.data.players_spades_suit;
                //     for idx in 0..=3 {
                //         if min_suits[idx] >= 2 || spades_count[idx] <= 3 {
                //             seat_condition[idx] = false;
                //         }
                //     }
                // }
                // for sid in 0..=3 {
                //     if seat_condition[sid]
                //         && utils::Utils::get_team_by_player_id(sid, 1) == fail_team_id
                //     {
                //         write_pool_type = 2;
                //         mark_sead_id = sid as i8;
                //         break;
                //     }
                // }
                // seat_condition = [true, true, true, true];
                // if write_pool_type == 0 {
                //     //同一位置每小局杀牌成功次数都大于1次，最终失败，该位置为1号位，归入波谷牌库
                //     for round in rounds {
                //         let break_win = round.data.players_break_win;
                //         for idx in 0..=3 {
                //             if break_win[idx] < 2 {
                //                 seat_condition[idx] = false;
                //             }
                //         }
                //     }
                //     for sid in 0..=3 {
                //         if seat_condition[sid]
                //             && utils::Utils::get_team_by_player_id(sid, 1) == fail_team_id
                //         {
                //             write_pool_type = 2;
                //             mark_sead_id = sid as i8;
                //             break;
                //         }
                //     }
                // }

                if write_pool_type == 0 {
                    if match_data.rounds.len() == 2 {
                        let round_one = &match_data.rounds[0];
                        let round_one_teams = &round_one.data.teams;
                        let team_a = round_one_teams[0].match_score;
                        let team_b = round_one_teams[1].match_score;

                        let round_two = &match_data.rounds[1];
                        if team_a > 0 && team_b > 0 && (team_a - team_b).abs() > 30 {
                            //双方都达成叫分
                            let mut is_all_finish_bid = true;
                            for idx in 0..=3 {
                                let bids = &round_two.bids;
                                let tricks = &round_two.tricks;
                                if tricks[idx] < bids[idx] {
                                    is_all_finish_bid = false;
                                    break;
                                }
                                if bids[idx] == 0 && tricks[idx] > 0 {
                                    is_all_finish_bid = false;
                                    break;
                                }
                            }
                            if is_all_finish_bid {
                                if team_a > team_b && win_team_id == 1 {
                                    if round_one.bids[0] > round_one.bids[2] {
                                        mark_sead_id = 0;
                                    } else {
                                        mark_sead_id = 2;
                                    }
                                    write_pool_type = 2;
                                    write_conditon_type = 1;
                                } else if team_a < team_b && win_team_id == 0 {
                                    //记录反超队伍中 第二局贡献大的位置
                                    if round_two.bids[1] > round_two.bids[3] {
                                        mark_sead_id = 1;
                                    } else {
                                        mark_sead_id = 3;
                                    }
                                    write_pool_type = 2;
                                    write_conditon_type = 1;
                                }
                            }
                        }
                    }
                }

                //任意小局叫0成功，且最终失败，分差大于20分，该位置为1号位，归入波谷牌库
                if write_pool_type == 0 {
                    seat_condition = [false, false, false, false];
                    for round in rounds {
                        let bids = &round.bids;
                        let tricks = &round.tricks;
                        for sid in 0..=3 {
                            let bid = bids[sid];
                            let trick = tricks[sid];
                            if bid == 0 && trick == 0 {
                                //bin nil fail
                                seat_condition[sid] = true;
                            }
                        }
                    }
                    for sid in 0..=3 {
                        if seat_condition[sid]
                            && Utils::get_team_by_player_id(sid, 1) == fail_team_id
                            && delta > 20
                        {
                            write_pool_type = 2;
                            mark_sead_id = sid as i8;
                            write_conditon_type = 2;
                            break;
                        }
                    }
                }

                if write_pool_type == 0 {
                    if match_data.rounds.len() == 2 {
                        //每局都得正分
                        let mut is_always_finish_bid = true;
                        for round in &match_data.rounds {
                            for team in &round.data.teams {
                                if team.match_score <= 0 {
                                    is_always_finish_bid = false;
                                    break;
                                }
                            }
                        }
                        if is_always_finish_bid {
                            let round_one = &match_data.rounds[0];
                            let round_two = &match_data.rounds[1];
                            for sid in 0..=3 {
                                let s_team_id = utils::Utils::get_team_by_player_id(sid, 1);
                                if round_one.bids[sid] + round_two.bids[sid] >= 7
                                    && round_one.bids[sid] <= round_one.tricks[sid]
                                    && round_two.bids[sid] <= round_two.tricks[sid]
                                {
                                    if s_team_id == fail_team_id {
                                        // let partner_id = Utils::get_partner_player_id(sid);
                                        let win_score =
                                            match_data.team_scores[win_team_id as usize];
                                        if win_score - match_data.team_scores[fail_team_id] > 20
                                            && win_score > 0
                                        {
                                            mark_sead_id = sid as i8;
                                            write_pool_type = 2;
                                            write_conditon_type = 3;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //任意小局有人叫0，根据结果分数归入Pool 2
            if write_pool_type == 0 {
                for round in rounds {
                    let bids = &round.bids;
                    for sid in 0..=3 {
                        let bid = bids[sid];
                        if bid == 0 {
                            //bin nil fail
                            write_pool_type = 3;
                            break;
                        }
                    }
                }
            }
            //任意小局每个人的最少花色牌都小于2，根据结果分数归入对应分数的牌库2
            if write_pool_type == 0 {
                for round in rounds {
                    let suit_counts = round.data.players_min_suit;
                    let mut is_suit_less_two = true;
                    for ele in suit_counts {
                        if ele >= 2 {
                            is_suit_less_two = false;
                        }
                    }
                    if is_suit_less_two {
                        write_pool_type = 3;
                    }
                }
            }
            let mut score_id = (delta / 40) * 40;
            if write_pool_type == 0 {
                if score_id > 80 {
                    score_id = 80;
                }
                if score_id < 0 && score_id > 100 {
                    return Err(std::io::Error::new(
                        std::io::ErrorKind::Other,
                        "score is bigger than 100",
                    ));
                }
                write_pool_type = 4;
            }
            match_data.score_id = score_id;
            match_data.group_id = String::from(score_id.to_string());
            match_data.write_pool_type = write_pool_type;
            match_data.write_condition_type = write_conditon_type;
            let rounds = &match_data.rounds;
            for round in rounds {
                //不需要进行交换
                let mut round_cards: Vec<i16> = Vec::new();
                round_cards.extend(&round.piles[0]);
                round_cards.extend(&round.piles[1]);
                round_cards.extend(&round.piles[2]);
                round_cards.extend(&round.piles[3]);
                match_data.cards.push(round_cards);

                match_data.bids.push(round.bids.clone());
                match_data.tricks.push(round.tricks.clone());
            }
            //波峰 波谷有mark的seat id 进行交换
            if mark_sead_id > -1 {
                let mark_partner_id = Utils::get_partner_player_id(mark_sead_id as usize);
                let ranks = &mut match_data.banker_ranks;
                let mark_rank = ranks[mark_sead_id as usize].clone();
                let mark_partner_rank = ranks[mark_partner_id].clone();
                // let team_id = Utils::get_team_by_player_id(mark_sead_id as usize, 1);
                if write_pool_type == 1 {
                    //波峰
                    // 1 3 交换
                    if mark_rank > mark_partner_rank {
                        ranks[mark_sead_id as usize] = mark_partner_rank;
                        ranks[mark_partner_id] = mark_rank;
                    }
                } else if write_pool_type == 2 {
                    //波谷 2 4 交换
                    if mark_rank < mark_partner_rank {
                        ranks[mark_sead_id as usize] = mark_partner_rank;
                        ranks[mark_partner_id] = mark_rank;
                    }
                }
            }
        } else if mode == 2 {
            let fid = match_data.team_win_id as usize;
            let fs = match_data.team_scores[fid];
            let sid = match_data.sec_team_id as usize;
            let ss = match_data.team_scores[sid];
            let tid = match_data.third_team_id as usize;
            let ts = match_data.team_scores[tid];
            let fts = fs - ts;
            let lid = match_data.last_team_id as usize;
            let ls = match_data.team_scores[lid];
            let fls = fs - ls;

            if check_crest {
                let is_score_win = match_data.team_scores[fid] >= final_score_2;
                if is_score_win {
                    //一局结束，通过赢分获得第一名，且领先第二名20分以上，第1名作为1号位，归入波峰牌库 增加没有叫0的条件
                    let mut is_bid_nil_once = false;
                    for round in &match_data.rounds {
                        let bid = round.bids[0];
                        if bid == 0 {
                            is_bid_nil_once = true;
                        }
                    }
                    if (fs - ss) > 20 && !is_bid_nil_once {
                        write_pool_type = 1;
                        write_conditon_type = 1;
                    }
                    //同一位置每小局杀牌成功次数都大于2次，且最终赢分获得第一名，该位置为1号位，归入波峰牌库
                    // if write_pool_type == 0 {
                    //     let mut is_break_win = true;
                    //     for round in rounds {
                    //         let break_wins = round.data.players_break_win;
                    //         if break_wins[fid] < 2 {
                    //             is_break_win = false;
                    //             break;
                    //         }
                    //     }
                    //     if is_break_win {
                    //         write_pool_type = 1;
                    //     }
                    // }
                    //任意小局叫0成功，通过赢分获得第一名,第1名作为1号位，归入波峰牌库
                    if write_pool_type == 0 {
                        let mut is_bid_nil = false;
                        for round in rounds {
                            let bids = &round.bids;
                            if bids[fid] == 0 {
                                is_bid_nil = true;
                                break;
                            }
                        }
                        if is_bid_nil {
                            write_pool_type = 1;
                            write_conditon_type = 2;
                        }
                    }

                    // if write_pool_type == 0 {
                    //     if match_data.rounds.len() == 2 {
                    //         let round_one = &match_data.rounds[0];
                    //         let round_one_teams = &round_one.data.teams;
                    //         let score_f = round_one_teams[fid].match_score;
                    //         let mut is_lose_f = true;
                    //         for idx in 0..=3 {
                    //             let score = round_one_teams[idx].match_score;
                    //             if score < score_f {
                    //                 is_lose_f = false;
                    //                 break;
                    //             }
                    //         }
                    //         if is_lose_f && fs - ts > 10 {
                    //             write_pool_type = 1;
                    //             write_conditon_type = 3;
                    //         }
                    //     }
                    // }
                }
            }
            if check_through {
                //同一位置每小局最少花色小于2张且黑桃张数都大于3张，最终第3或第4，该位置为1号位，归入波谷牌库
                let mut seat_condition = [true, true, true, true];
                // if write_pool_type == 0 {
                //     for round in rounds {
                //         let min_suits = round.data.players_min_suit;
                //         let spades_count = round.data.players_spades_suit;
                //         for idx in 0..=3 {
                //             if min_suits[idx] >= 2 || spades_count[idx] <= 3 {
                //                 seat_condition[idx] = false;
                //             }
                //         }
                //     }
                //     for sid in 0..=3 {
                //         if seat_condition[sid] && (sid == lid || sid == tid) {
                //             write_pool_type = 2;
                //             mark_sead_id = sid as i8;
                //             break;
                //         }
                //     }
                // }
                // //同一位置每小局杀牌成功次数都大于1次，最终第3或第4，该位置为1号位，归入波谷牌库
                // if write_pool_type == 0 {
                //     for round in rounds {
                //         let break_win = round.data.players_break_win;
                //         for idx in 0..=3 {
                //             if break_win[idx] < 2 {
                //                 seat_condition[idx] = false;
                //             }
                //         }
                //     }
                //     for sid in 0..=3 {
                //         if seat_condition[sid] && (sid == lid || sid == tid) {
                //             write_pool_type = 2;
                //             mark_sead_id = sid as i8;
                //             break;
                //         }
                //     }
                // }
                // //任意小局叫0失败，且最终第3或第4，和第1名分差大于20分，该位置为1号位，归入波谷牌库
                // if write_pool_type == 0 {
                //     seat_condition = [false, false, false, false];
                //     for round in rounds {
                //         let bids = &round.bids;
                //         let tricks = &round.tricks;
                //         for sid in 0..=3 {
                //             let bid = bids[sid];
                //             let trick = tricks[sid];
                //             if bid == 0 && trick > 0 {
                //                 //bin nil fail
                //                 seat_condition[sid] = true;
                //             }
                //         }
                //     }
                //     for sid in 0..=3 {
                //         if seat_condition[sid] && (sid == tid && fts > 20 || sid == lid && fls > 20)
                //         {
                //             write_pool_type = 2;
                //             mark_sead_id = sid as i8;
                //             break;
                //         }
                //     }
                // }
                if write_pool_type == 0 {
                    for round in rounds {
                        let bids = &round.bids;
                        let tricks = &round.tricks;
                        for (idx, &value) in bids.iter().enumerate() {
                            if value == 0 && tricks[idx] == 0 {
                                if idx != fid {
                                    write_pool_type = 2;
                                    write_conditon_type = 1;
                                    mark_sead_id = idx as i8;
                                }
                            }
                        }
                    }
                }

                if write_pool_type == 0 && match_data.rounds.len() == 1 {
                    for round in rounds {
                        let bids = &round.bids;
                        let tricks = &round.tricks;
                        for (idx, &value) in bids.iter().enumerate() {
                            if value >= 4 && tricks[idx] >= value {
                                let score = match_data.team_scores[idx];
                                if idx != fid && (fs - score) > 5{
                                    write_pool_type = 2;
                                    write_conditon_type = 2;
                                    mark_sead_id = idx as i8;
                                    break;
                                }
                            }
                        }
                    }
                }
                // if write_pool_type == 0 {
                //     for idx in 0..=3 {
                //         let score = match_data.team_scores[idx];
                //         if score >= 60 && idx != fid {
                //             write_pool_type = 2;
                //             write_conditon_type = 3;
                //             mark_sead_id = idx as i8;
                //             break;
                //         }
                //     }
                // }
            }

            //任意小局有人叫0，根据结果分数归入Pool 2
            if write_pool_type == 0 {
                for round in rounds {
                    let bids = &round.bids;
                    for sid in 0..=3 {
                        let bid = bids[sid];
                        if bid == 0 {
                            //bin nil fail
                            write_pool_type = 3;
                            break;
                        }
                    }
                }
            }
            //任意小局每个人的最少花色牌都小于2，根据结果分数归入对应分数的牌库2
            if write_pool_type == 0 {
                for round in rounds {
                    let suit_counts = round.data.players_min_suit;
                    let mut is_suit_less_two = true;
                    for ele in suit_counts {
                        if ele >= 2 {
                            is_suit_less_two = false;
                        }
                    }
                    if is_suit_less_two {
                        write_pool_type = 3;
                    }
                }
            }
            //其他情况落入牌库1
            if write_pool_type == 0 {
                write_pool_type = 4
            }

            let delta = (fs - ts).abs() as i32 + (fs - ls).abs() as i32;
            if delta < 0 {
                return Err(std::io::Error::new(
                    std::io::ErrorKind::Other,
                    "score is not in scope >=0 and <180",
                ));
            }
            let score_fs = (delta / 60) * 60;

            let group_id = format!("{0}", score_fs);
            match_data.group_id = group_id;
            match_data.write_pool_type = write_pool_type;
            match_data.write_condition_type = write_conditon_type;
            let rounds = &match_data.rounds;
            for round in rounds {
                // let aa: &Vec<i16> = &round.piles[fid];
                // let ab: &Vec<i16> = &round.piles[sid];
                // let ba: &Vec<i16> = &round.piles[tid];
                // let bb: &Vec<i16> = &round.piles[lid];

                // let mut round_cards: Vec<i16> = Vec::new();
                // round_cards.extend(aa.into_iter());
                // round_cards.extend(ab.into_iter());
                // round_cards.extend(ba.into_iter());
                // round_cards.extend(bb.into_iter());
                let mut round_cards: Vec<i16> = Vec::new();
                round_cards.extend(&round.piles[0]);
                round_cards.extend(&round.piles[1]);
                round_cards.extend(&round.piles[2]);
                round_cards.extend(&round.piles[3]);
                match_data.cards.push(round_cards);

                match_data.bids.push(round.bids.clone());
                match_data.tricks.push(round.tricks.clone());
            }
            if mark_sead_id > -1 {
                if write_pool_type == 2 {
                    let ranks = &mut match_data.banker_ranks;
                    let mark_rank = ranks[mark_sead_id as usize];
                    if mark_rank != 4 {
                        //找到4号位的人交换下
                        if let Some(index) = ranks.iter().position(|&x| x == 4) {
                            ranks[index] = mark_rank;
                            ranks[mark_sead_id as usize] = 4;
                        }
                    }
                }
            }
            // let delta = (match_data.team_scores[fid] - match_data.team_scores[tid]).abs() as i32;
            // let score_fs = (delta / 60) * 60;

            // let delta2 = (match_data.team_scores[fid] - match_data.team_scores[lid]).abs() as i32;
            // let mut score_ls = (delta2 / 60) * 60;
            // if score_ls > 120 {
            //     score_ls = 120;
            // }

            // if score_fs >= 0 && score_fs < 180 && score_ls >= 0 && score_ls < 180 {
            //     let group_id = format!("{0}_{1}", score_fs, score_ls);
            //     match_data.group_id = group_id;
            //     let rounds = &match_data.rounds;
            //     for round in rounds {
            //         // let aa: &Vec<i16> = &round.piles[fid];
            //         // let ab: &Vec<i16> = &round.piles[sid];
            //         // let ba: &Vec<i16> = &round.piles[tid];
            //         // let bb: &Vec<i16> = &round.piles[lid];

            //         // let mut round_cards: Vec<i16> = Vec::new();
            //         // round_cards.extend(aa.into_iter());
            //         // round_cards.extend(ab.into_iter());
            //         // round_cards.extend(ba.into_iter());
            //         // round_cards.extend(bb.into_iter());
            //         let mut round_cards: Vec<i16> = Vec::new();
            //         round_cards.extend(&round.piles[0]);
            //         round_cards.extend(&round.piles[1]);
            //         round_cards.extend(&round.piles[2]);
            //         round_cards.extend(&round.piles[3]);
            //         match_data.cards.push(round_cards);
            //     }
            // } else {
            //     return Err(std::io::Error::new(
            //         std::io::ErrorKind::Other,
            //         "score is not in scope >=0 and <180",
            //     ));
            // }
        }
    }
    if match_data.cards.len() == 0 {
        return Err(std::io::Error::new(
            std::io::ErrorKind::Other,
            "match has no rounds",
        ));
    }
    Ok(m.match_data)
}
